package com.sentrix.auto.printercenter.infrastructure.agentserver;

import com.sentrix.auto.printercenter.common.IdGenerator;
import com.sentrix.auto.printercenter.infrastructure.agentserver.dto.BaseWebSocketResMsg;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.Assert;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;

/**
 * WebSocket同步消息处理器，负责管理请求-响应的同步等待逻辑
 */
@Slf4j
public class WebSocketResSyncHandler {
    private final Map<String, BaseWebSocketResMsg> responseMap = new ConcurrentHashMap<>();
    private final Map<String, CountDownLatch> latchMap = new ConcurrentHashMap<>();

    private static final class InstanceHolder {
        private static final WebSocketResSyncHandler instance = new WebSocketResSyncHandler();
    }

    private WebSocketResSyncHandler() {
    }

    public static WebSocketResSyncHandler instance() {
        return InstanceHolder.instance;
    }

    /**
     * 生成唯一请求ID
     */
    public String generateRequestId() {
        return IdGenerator.generateId();
    }

    public BaseWebSocketResMsg waitForResponse(String uid, long timeout) {
        Assert.hasText(uid, "请求ID不能为空");

        CountDownLatch latch = new CountDownLatch(1);
        latchMap.put(uid, latch);
        BaseWebSocketResMsg resMsg = null;
        try {
            boolean success = latch.await(timeout, TimeUnit.SECONDS);
            if (!success) {
                log.error("请求超时，请求ID：{}", uid);
                resMsg = new BaseWebSocketResMsg(uid, false, "waiting res message timeout!");
            } else {
                resMsg = responseMap.get(uid);
            }
        } catch (InterruptedException e) {
            log.info("处理响应消息异常", e);
            resMsg = new BaseWebSocketResMsg(uid, false, "waiting res message exception!");
        } finally {
            cleanup(uid);
        }
        return resMsg;
    }

    /**
     * 处理响应消息
     *
     * @param response
     */
    public void handleResponse(BaseWebSocketResMsg response) {
        Assert.notNull(response, "响应消息不能为null");
        Assert.hasText(response.getUid(), "响应消息中requestId不能为空");

        CountDownLatch latch = latchMap.get(response.getUid());
        if (latch != null) {
            responseMap.put(response.getUid(), response);
            latch.countDown();
        } else {
            log.info("消息无同步处理器，不处理");
        }
    }

    /**
     * 清理请求相关的资源
     *
     * @param requestId 请求ID
     */
    private void cleanup(String requestId) {
        latchMap.remove(requestId);
        responseMap.remove(requestId);
    }

}
